/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package webidewar.jsf;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import org.WebIDE.ejb.entities.Replies;
import org.WebIDE.ejb.entities.Topics;
import org.WebIDE.ejb.entities.Users;
import org.WebIDE.ejb.sessions.RepliesFacadeRemote;
import org.WebIDE.ejb.sessions.TopicsFacade;
import org.WebIDE.ejb.sessions.TopicsFacadeRemote;
import webidewar.jsf.util.JsfUtil;
import org.WebIDE.ejb.sessions.exceptions.NonexistentEntityException;
import webidewar.jsf.util.PagingInfo;

/**
 *
 * @author huy
 */
public class TopicsController {
    
    private TopicsFacadeRemote Facade;
    
    @EJB
    public void setFacade(TopicsFacadeRemote Facade) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.getApplication().getELResolver().setValue(facesContext.getELContext(), null, "topicsJpa", Facade);

        this.Facade = Facade;
    }

    public TopicsController() {
        //FacesContext facesContext = FacesContext.getCurrentInstance();
        //Facade = (TopicsFacade) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "topicsJpa");
        pagingInfo = new PagingInfo();
        converter = new TopicsConverter();
    }
    private Topics topics = null;
    private List<Topics> topicsItems = null;
    //private TopicsFacade Facade = null;
    private TopicsConverter converter = null;
    private PagingInfo pagingInfo = null;

    public PagingInfo getPagingInfo() {
        if (pagingInfo.getItemCount() == -1) {
            pagingInfo.setItemCount(Facade.getTopicsCount());
        }
        return pagingInfo;
    }

    public SelectItem[] getTopicsItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(Facade.findTopicsEntities(), false);
    }

    public SelectItem[] getTopicsItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(Facade.findTopicsEntities(), true);
    }

    public Topics getTopics() {
        if (topics == null) {
            topics = (Topics) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentTopics", converter, null);
        }
        if (topics == null) {
            topics = new Topics();
        }
        return topics;
    }

    public String listSetup() {
        //reset(true);
        return "topics_list";
    }

    public String createSetup() {
        //(false);
        topics = new Topics();
        return "topics_create";
    }

    public String create() {
        try {
            int newTopicID = Facade.getMaxID() + 1;
            topics.setId(newTopicID);
            topics.setUserName(new Users("guest"));
            Facade.create(topics);
            
            reply.setId(null);
            reply.setTopicId(topics);
            reply.setUserName(new Users("guest"));
            reply.setTitles(topics.getTitle());
            Date today = new Date();    // hôm nay
            reply.setCreated(today);
            reply.setModified(today);
            replyBean.create(reply);
            
            JsfUtil.addSuccessMessage("Topics was successfully created.");
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return listSetup();
    }

    public String detailSetup() {
        return scalarSetup("topics_detail");
    }

    public String editSetup() {
        return scalarSetup("topics_edit");
    }

    private String scalarSetup(String destination) {
        reset(false);
        topics = (Topics) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentTopics", converter, null);
        if (topics == null) {
            String requestTopicsString = JsfUtil.getRequestParameter("jsfcrud.currentTopics");
            JsfUtil.addErrorMessage("The topics with id " + requestTopicsString + " no longer exists.");
            return relatedOrListOutcome();
        }
        return destination;
    }

    public String edit() {
        String topicsString = converter.getAsString(FacesContext.getCurrentInstance(), null, topics);
        String currentTopicsString = JsfUtil.getRequestParameter("jsfcrud.currentTopics");
        if (topicsString == null || topicsString.length() == 0 || !topicsString.equals(currentTopicsString)) {
            String outcome = editSetup();
            if ("topics_edit".equals(outcome)) {
                JsfUtil.addErrorMessage("Could not edit topics. Try again.");
            }
            return outcome;
        }
        try {
            Facade.edit(topics);
            JsfUtil.addSuccessMessage("Topics was successfully updated.");
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return listSetup();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return detailSetup();
    }

    public String destroy() {
        String idAsString = JsfUtil.getRequestParameter("jsfcrud.currentTopics");
        Integer id = new Integer(idAsString);
        try {
            Facade.destroy(id);
            JsfUtil.addSuccessMessage("Topics was successfully deleted.");
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return relatedOrListOutcome();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return relatedOrListOutcome();
    }

    private String relatedOrListOutcome() {
        String relatedControllerOutcome = relatedControllerOutcome();
        if (relatedControllerOutcome != null) {
            return relatedControllerOutcome;
        }
        return listSetup();
    }

    public List<Topics> getTopicsItems() {
        if (topicsItems == null) {
            //getPagingInfo();
            topicsItems = Facade.findTopicsEntities();//(pagingInfo.getItemCount(), pagingInfo.getFirstItem());
        }
        return topicsItems;
    }

    public String next() {
        reset(false);
        getPagingInfo().nextPage();
        return "topics_list";
    }

    public String prev() {
        reset(false);
        getPagingInfo().previousPage();
        return "topics_list";
    }

    private String relatedControllerOutcome() {
        String relatedControllerString = JsfUtil.getRequestParameter("jsfcrud.relatedController");
        String relatedControllerTypeString = JsfUtil.getRequestParameter("jsfcrud.relatedControllerType");
        if (relatedControllerString != null && relatedControllerTypeString != null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Object relatedController = context.getApplication().getELResolver().getValue(context.getELContext(), null, relatedControllerString);
            try {
                Class<?> relatedControllerType = Class.forName(relatedControllerTypeString);
                Method detailSetupMethod = relatedControllerType.getMethod("detailSetup");
                return (String) detailSetupMethod.invoke(relatedController);
            } catch (ClassNotFoundException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            }
        }
        return null;
    }

    private void reset(boolean resetFirstItem) {
        topics = null;
        topicsItems = null;
        pagingInfo.setItemCount(-1);
        if (resetFirstItem) {
            pagingInfo.setFirstItem(0);
        }
    }

    public void validateCreate(FacesContext facesContext, UIComponent component, Object value) {
        Topics newTopics = new Topics();
        String newTopicsString = converter.getAsString(FacesContext.getCurrentInstance(), null, newTopics);
        String topicsString = converter.getAsString(FacesContext.getCurrentInstance(), null, topics);
        if (!newTopicsString.equals(topicsString)) {
            createSetup();
        }
    }

    public Converter getConverter() {
        return converter;
    }

    ///// my code /////
    public class TopicComposite implements Comparable<TopicComposite> {
        private Topics topic;
        public Topics getTopic() {
            return topic;
        }
        
        private int repliesNum;
        public int getRepliesNum() {
            return repliesNum;
        }
        
        private Date lastModified;
        public Date getLastModified() {
            return lastModified;
        }
        
        private String lastModifiedUser;
        public String getLastModifiedUser() {
            return lastModifiedUser;
        }
        
        public int compareTo(TopicComposite arg0) {
            //throw new UnsupportedOperationException("Not supported yet.");
            return arg0.lastModified.compareTo(this.lastModified);
        }
    }

    @EJB
    private RepliesFacadeRemote replyBean;
/*
    @EJB
    public void setReplyBean(RepliesFacadeRemote replyBean) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.getApplication().getELResolver().setValue(facesContext.getELContext(), null, "repliesJpa", replyBean);

        this.replyBean = replyBean;
    }
    */
    private ArrayList<TopicComposite> topicsComp = null;
    public ArrayList<TopicComposite> getTopicsComp() {
        // lấy tất cả các topic hiện có
        topicsItems = getTopicsItems();
        if (topicsItems == null)
            return null;
        
        topicsComp = new ArrayList<TopicComposite>();
        for (int i=0; i<topicsItems.size(); i++) {
            TopicComposite tc = new TopicComposite();
            
            tc.topic = topicsItems.get(i);
            Topics tmp = new Topics(topicsItems.get(i).getId());
            tc.repliesNum = replyBean.getRepliesCount(tmp) - 1;
            List<Object> lo = replyBean.getLastModified(tmp);
            Object[] _lo = (Object[]) lo.get(0);
            tc.lastModified = (Date) _lo[0];
            tc.lastModifiedUser = ((Users)_lo[1]).getUserName();
            
            topicsComp.add(tc);
        }
        // sort lại topicComposite giảm dần theo lastModified
        Collections.sort(topicsComp);
        
        return topicsComp;
    }
    
    private Replies reply = new Replies();
    public Replies getReply() {
        return reply;
    }
    
}
